<template>
  <zc-search
    :search="search"
    @changeData="changeData"
    :request="request"
    :isCollpase="isCollpase"
    :loading="loading"
    v-if="showSearch == true"
  ></zc-search>
  <el-card style="margin-top: 24px" :style="styleValue">
    <div class="header">
      <slot name="header"> </slot>
    </div>
    <el-table
      v-loading="loading"
      :height="height"
      :data="tableRefData"
      style="width: 100%"
      :header-cell-style="{ background: '#ddd', color: '#000' }"
    >
      <!-- 默认插槽 -->
      <slot></slot>
      <!-- 1.传入showSelectColumn时展示的全选列 -->
      <template v-if="showSelectColumn">
        <el-table-column type="selection" />
      </template>
      <!-- 2.传入showIndexColumn时展示的序号列 -->
      <template v-if="showIndexColumn">
        <el-table-column type="index" label="序号" width="70px" />
      </template>
      <!--  -->
      <template v-for="item in column">
        <!-- expand 支持 tsx 语法 && 作用域插槽 (tsx > slot) -->
        <el-table-column
          v-bind="item"
          show-overflow-tooltip
          :align="item.align ?? 'left'"
          v-slot="scope"
        >
          <template v-if="item.render">
            <component :is="item.render" :row="scope.row" v-if="item.render">
            </component
          ></template>
          <template v-else-if="item.slotName">
            <slot :name="item.slotName" :row="scope.row" />
          </template>
          <template v-else-if="item.showImage">
            <el-image
              preview-teleported
              :hide-on-click-modal="true"
              @close=""
              style="width: 100px; height: 100px"
              :src="scope.row?.[item.prop!]"
              :initial-index="4"
              :preview-src-list="[scope.row?.[item.prop!]]"
              :zoom-rate="0.8"
              fit="cover"
            />
          </template>
        </el-table-column>
      </template>
      <!-- 无数据 -->
      <template #empty>
        <empty></empty>
      </template>
    </el-table>
    <!-- 分页 -->
    <div class="footer">
      <slot name="footer">
        <el-pagination
          :hide-on-single-page="true"
          v-model:pageNum="pageNum"
          v-model:page-size="pageSize"
          :style="{ marginTop: '24px', justifyContent: paginationAlign }"
          :page-sizes="[10, 20, 50, 100]"
          :layout="layout"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </slot>
    </div>
  </el-card>
</template>

<script lang="ts" setup>
import { ZCTableOption } from "@/model/zcTable";
import { StyleValue } from "vue";
import { $, $ref } from "vue/macros";

interface paginationConfig {
  total: boolean | string;
  sizes: boolean | string;
  jumper: boolean | string;
}
interface Props {
  tableData?: any[];
  column: ZCTableOption[];
  showIndexColumn?: boolean;
  showSelectColumn?: boolean;
  showSearch?: boolean;
  isCollpase?: boolean;
  height?: string;
  extraSearch?: ZCTableOption[];
  pagination?: Partial<paginationConfig>;
  request?: (params?: any) => Promise<any>;
  total?: number;
  childrenProps?: object;
  style?: StyleValue;
  paginationAlign?: string;
}

const props = withDefaults(defineProps<Props>(), { showSearch: true });

let loading = $ref(false);
const tableRefData = ref(props.tableData || []);
const isShowTable = ref<boolean>(true);

// style样式
const styleValue = computed(() => {
  return props.style;
});
// 当前页
let pageNum = ref<number>(1);
// 当前pagesize
let pageSize = ref<number>(10);
// 分页配置
let pageConfig = reactive<paginationConfig>({
  total: "",
  sizes: "",
  jumper: "",
});
const urlList = ref();
// 处理表单数据，只留显示的表单
const search = computed(() => {
  if (props.extraSearch) {
    let newArr = [];
    newArr = props.column?.filter((item) => item.show !== false);
    newArr.push(...props.extraSearch);
    return newArr;
  }
  return props.column?.filter((item) => item.show !== false);
});

// 刷新列表
const reload = () => {
  isShowTable.value = false;
  nextTick(() => {
    isShowTable.value = true;
    getData({
      pageNum: pageNum.value,
      pageSize: pageSize.value,
    });
  });
};

// 请求数据
const getData = async (params?: any) => {
  loading = true;
  if (props.request) {
    try {
      const re = await props.request({ ...params });
      tableRefData.value = re ?? [];
    } finally {
      loading = false;
    }
  }
  loading = false;
};
onMounted(() => {
  getData({ pageNum: 1, pageSize: 10 });
});
let filterParams = reactive<any>({});

// 筛选数组函数
// const handleData = (prop: any) => {
//   return (tableRefData.value = tableRefData.value.filter((item) => {
//     return Object.keys(prop).every((e) => {
//       return prop[e] == item[e];
//     });
//   }));
// };

// 筛选数组
const changeData = async (prop: any) => {
  filterParams = prop;
  if (pageNum.value !== 1) {
    return (pageNum.value = 1);
  }
  await getData({
    ...prop,
    pageNum: pageNum.value,
    pageSize: pageSize.value,
  });
};
// 监听pageSize和pageNum
watch([pageSize, pageNum], (newValue) => {
  let paginationObj: { pageNum: number; pageSize: number } = {
    pageNum: 0,
    pageSize: 0,
  };
  paginationObj.pageSize = newValue[0];
  paginationObj.pageNum = newValue[1];
  getData({ ...paginationObj, ...filterParams });
});
// pagesize改变
const handleSizeChange = (val: number) => {
  pageSize.value = val;
};
// pageNumber改变
const handleCurrentChange = (val: number) => {
  pageNum.value = val;
};

// 获取数据total
const totalData = computed(() => {
  return tableRefData.value?.length || 0;
});
// 配置分页

props.pagination &&
  Object.keys(props.pagination as object).forEach((item: string) => {
    if (props.pagination?.[item as keyof paginationConfig] == true) {
      pageConfig[item as keyof paginationConfig] = item;
    }
  });

// 分页布局
const layout = computed(() => {
  if (!props.pagination) {
    return "total, sizes, prev, pager, next, jumper";
  } else {
    return `${pageConfig.total}, ${pageConfig.sizes}, prev, pager, next, ${pageConfig.jumper}`;
  }
});
defineExpose({ reload });
</script>
